﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using System.Xml.Linq;
using NetAcademia.Web.Mvc;

namespace HtmlLaundryTests
{
    [TestClass]
    public class WashTest
    {


        [TestMethod]
        public void StrangeErrorTest()
        {
            string whitelist = "<tags><h2></h2></tags>";
            string html = "<h2>Egy csatolmány</h2> FullName";

            string accepted = "<h2>Egy csatolmány</h2> FullName";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);

        }

        [TestMethod]
        public void BasicTest()
        {
            string whitelist = "<tags><b></b></tags>";
            string html =     "alma <b>barack</b> citrom <nincs>dinnye</nincs>";
            string accepted = "alma <b>barack</b> citrom dinnye";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }


        [TestMethod]
        public void UnClosedTest()
        {
            string whitelist = "<tags><b></b><span/></tags>";
            string html =     "alma <b>barack <span>citrom dinnye</span> eper";
            string accepted = "alma <b>barack <span>citrom dinnye</span> eper</b>";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }

        [TestMethod]
        public void UnOpenedTest()
        {
            string whitelist = "<tags><b></b><span/></tags>";
            string html =     "alma barack <span>citrom dinnye</span> eper</b>";
            string accepted = "alma barack <span>citrom dinnye</span> eper";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }

        [TestMethod]
        public void OverlappingTest()
        {
            string whitelist = "<tags><b></b><span/></tags>";
            string html =     "alma barack <span>citrom <b>dinnye</span> eper</b>";
            string accepted = "alma barack <span>citrom <b>dinnye</b></span> eper";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }

        [TestMethod]
        public void UppercaseTest()
        {
            string whitelist = "<tags><b></b></tags>";
            string html =     "alma <B>barack</B> citrom";
            string accepted = "alma <b>barack</b> citrom";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }

        [TestMethod]
        public void InconsistentUppercaseTest()
        {
            string whitelist = "<tags><b></b></tags>";
            string html =     "alma <B>barack</b> citrom";
            string accepted = "alma <b>barack</b> citrom";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }


        [TestMethod]
        public void BasicAttributeRemoveTest()
        {
            string whitelist = "<tags><b></b></tags>";
            string html =     "alma <b style=\"fontsize: 1em\">barack</b> citrom";
            string accepted = "alma <b>barack</b> citrom";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }


        [TestMethod]
        public void BasicAttributePreserveTest()
        {
            string whitelist = "<tags><b style=\"\"></b></tags>";
            string html = "alma <b style=\"fontsize: 1em\">barack</b> citrom";
            string accepted = "alma <b style=\"fontsize: 1em\">barack</b> citrom";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }

        [TestMethod]
        public void RegexAttributePreserveRemoveTest()
        {
            string whitelist = "<tags><b align=\"(value1)|(value2)\"></b></tags>";
            string html1 =     "alma <b align=\"fontsize: 1em\">barack</b> citrom";
            string accepted1 = "alma <b>barack</b> citrom";

            string html2 =     "alma <b align=\"value1\">barack</b> citrom";
            string accepted2 = "alma <b align=\"value1\">barack</b> citrom";

            string html3 =     "alma <b align=\"value1 megketto\">barack</b> citrom";
            string accepted3 = "alma <b>barack</b> citrom";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome1 = machine.CleanHtml(html1);
            string outcome2 = machine.CleanHtml(html2);
            string outcome3 = machine.CleanHtml(html3);

            Assert.AreEqual(accepted1, outcome1);
            Assert.AreEqual(accepted2, outcome2);
            Assert.AreEqual(accepted3, outcome3);
        }


        [TestMethod]
        public void RegexStyleAttributePreserveRemoveTest()
        {
            string whitelist = "<tags><b align=\"^(value1)$|^(value2)$\"></b></tags>";
            string html1 = "alma <b align=\"fontsize: 1em\">barack</b> citrom <nincs>dinnye</nincs>";
            string html2 = "alma <b align=\"value1\">barack</b> citrom <nincs>dinnye</nincs>";
            string html3 = "alma <b align=\"value1 megketto\">barack</b> citrom <nincs>dinnye</nincs>";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome1 = machine.CleanHtml(html1);
            string outcome2 = machine.CleanHtml(html2);
            string outcome3 = machine.CleanHtml(html3);

            Assert.AreEqual("alma <b>barack</b> citrom dinnye", outcome1);
            Assert.AreEqual("alma <b align=\"value1\">barack</b> citrom dinnye", outcome2);
            Assert.AreEqual("alma <b>barack</b> citrom dinnye", outcome3);
          
        }


        [TestMethod]
        public void NamespacedElementTest()
        {
            string whitelist = "<tags xmlns:ns=\"ns\"><ns:boo></ns:boo><b></b></tags>";
            string html =     "alma <ns:boo>barack</ns:boo> citrom <b>dinnye</b>";
            string accepted = "alma <ns:boo>barack</ns:boo> citrom <b>dinnye</b>";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }


        [TestMethod]
        public void HeaderElementsTest()
        {
            string whitelist = @"<tags>  
  <p style="" align=""></p>
  <h1 style="" align=""></h1>
  <h2 style="" align=""></h2>
  <h3 style="" align=""></h3>
  <h4 style="" align=""></h4></tags>";

            string html = "<h1>egyes</h1> <h9>kilences</h9> <p>sima</p>";
            string accepted = "<h1>egyes</h1> kilences <p>sima</p>";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }

        [TestMethod]
        public void NamespacedElementInconclusiveUppercaseTest()
        {
            string whitelist = "<tags xmlns:ns=\"ns\"><ns:boo></ns:boo><b></b></tags>";
            string html =     "alma <NS:boo>barack</ns:bOO> citrom <b>dinnye</b>";
            string accepted = "alma <ns:boo>barack</ns:boo> citrom <b>dinnye</b>";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }


        [TestMethod]
        public void NamespacedElementWithRottNamespaceOnSourceTest()
        {
            string whitelist = "<tags xmlns:ns=\"ns\"><ns:boo></ns:boo><b></b><treeroot /></tags>";
            string html =     "<treeroot xmlns:ns=\"http://someuri\">alma <ns:boo>barack</ns:boo> citrom <b>dinnye</b></treeroot>";
            string accepted = "<treeroot>alma <ns:boo>barack</ns:boo> citrom <b>dinnye</b></treeroot>";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }


        [TestMethod]
        public void AngleBracketTest01()
        {
            string whitelist = "<tags><b></b></tags>";
            string html = "alma < barack";
            string accepted = "alma &lt; barack";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }

        [TestMethod]
        public void AngleBracketTest02()
        {
            string whitelist = "<tags><b></b></tags>";
            string html = "alma > barack";
            string accepted = "alma &gt; barack";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }

        [TestMethod]
        public void AngleBracketTest03()
        {
            string whitelist = "<tags><b></b></tags>";
            string html = "alma > barack < citrom";
            string accepted = "alma &gt; barack &lt; citrom";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }

        [TestMethod]
        public void AngleBracketTest04()
        {
            string whitelist = "<tags><b></b></tags>";
            string html = "alma < barack > citrom";
            string accepted = "alma &lt; barack &gt; citrom";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }

        [TestMethod]
        public void AngleBracketTest05()
        {
            string whitelist = "<tags><b></b></tags>";
            string html = "alma <barack > citrom";
            string accepted = "alma  citrom";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }

        [TestMethod]
        public void AngleBracketTest06()
        {
            string whitelist = "<tags><b></b></tags>";
            string html = "5 <8 > 7";
            string accepted = "5 &lt;8 &gt; 7";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }


        [TestMethod]
        public void AngleBracketHackTest01()
        {
            string whitelist = "<tags><b></b></tags>";
            string html = "alma &lt;barack /&gt; citrom";
            string accepted = "alma &lt;barack /&gt; citrom";

            HtmlLaundry machine = new HtmlLaundry(whitelist);

            string outcome = machine.CleanHtml(html);

            Assert.AreEqual(accepted, outcome);
        }
    }
}
